﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MillerApp.CommonLib.Utility
{
    /// <summary>
    /// 身份证号码帮助类（主要提供15位身份证和18位身份证的互转及比对）
    /// </summary>
    public class IDCardHelper
    {
        //*********************************************************************************
        //将15位身份证转换成18位时，首先把出生年扩展4位，就是在原来15位号码的第6为数字后
        //增加一个19，然后在第17位数字后添加一位校验码，校验码是由前17位数字本体码加权求
        //和公式，通过计算模，再通过模得到对应的校验码。
        //计算校验码公式
        //（1）17位数字本体码加权求和公式
        //S=Sum(Ai*Wi),i=0,...,16,先对前17位数字的权求和
        //Ai:表示第i位置上的身份证号码数字值
        //Wi:表示第i位置上的加权因子
        //Wi;7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2
        //
        //（2）计算模
        //Y=mod(S,11)
        //（3）通过模得到对应的校验码
        //Y:0 1 2 3 4 5 6 7 8 9 10
        //校验码：1 0 X 9 8 7 6 5 4 3 2
        //*****************************************************************************
        /// <summary>
        /// 将15位的身份证号码转换成18位的身份证好码
        /// </summary>
        /// <param name="idCard">身份证号码</param>
        /// <returns>返回18位身份证号码,否则返回空字符串</returns>
        public static string Convert15to18(string idCard)
        {
            string code = idCard.Trim();//获得身份证号码
            if (code.Length == 15)//如果是15位则转换
            {
                char[] strJY = { '1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2' };
                int[] intJQ = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1 };
                string strTemp;
                int intTemp = 0;
                strTemp = code.Substring(0, 6) + "19" + code.Substring(6);
                for (int i = 0; i <= strTemp.Length - 1; i++)
                {
                    intTemp = intTemp + int.Parse(strTemp.Substring(i, 1)) * intJQ[i];
                }
                intTemp = intTemp % 11;
                return strTemp + strJY[intTemp];
            }
            else
            {
                if (code.Length == 18)//如果是18位直接返回
                {
                    return code;
                }
                return string.Empty;//如果即不是15位也不是18位则返回空
            }
        }

        /// <summary>
        /// 将18位的身份证号码转换成15位的身份证好码
        /// </summary>
        /// <param name="idCard">身份证号码</param>
        /// <returns>返回15位身份证号码,否则返回空字符串</returns>
        public static string Convert18to15(string idCard)
        {
             string code = idCard.Trim();//获得身份证号码
             if (code.Length == 18)//如果是18位则转换
             {
                 //430224 19 831108517 8
                 code = code.Substring(0, 6) + code.Substring(8, 9);
                 return code;
             }
             else if (code.Length == 15)
             {
                 return code;
             }
             else
             {
                 return string.Empty;
             }
        }

        /// <summary>
        /// 获得出身年月日
        /// </summary>
        /// <param name="idCard">身份证号码</param>
        /// <returns>返回出身年月日,如果没找到则返回空</returns>
        public static DateTime? GetBirthday(string idCard)
        {
            DateTime? birthday = null;
            string code = Convert15to18(idCard);//获得身份证号码
            if (code != string.Empty)
            {
                int year = Convert.ToInt32(code.Substring(6, 4));//获得身份证号码里面的年
                int month = Convert.ToInt32(code.Substring(10, 2));//获得身份证号码里面的月
                int day = Convert.ToInt32(code.Substring(12, 2));//获得身份证号码里面的日
                birthday = new DateTime(year, month, day);
            }
            return birthday;
        }

        /// <summary>
        /// 比较2身份证是否是同一人(可能身份证号码是15位的)
        /// </summary>
        /// <param name="idCard1">身份证号1</param>
        /// <param name="idCard2">身份证号2</param>
        /// <returns>如果相同的则返回True，否则返回False</returns>
        public static bool Compare(string idCard1, string idCard2)
        {
            if (idCard1 == null)
            {
                idCard1 = string.Empty;
            }
            if (idCard2 == null)
            {
                idCard2 = string.Empty;
            }
            idCard1 = idCard1.Trim();
            idCard2 = idCard2.Trim();
            if (idCard1 == idCard2)
            {
                return true;
            }
            if (idCard1.Length == 15 && idCard2.Length == 18)
            {
                idCard2 = Convert18to15(idCard2);
                if (idCard2 == idCard1)
                {
                    return true;
                }
            }
            if (idCard1.Length == 18 && idCard2.Length == 15)
            {
                idCard1 = Convert18to15(idCard1);
                if (idCard2 == idCard1)
                {
                    return true;
                }
            }
            return false;
        }
    }
}
